import BASE_URL from './baseConfig.js'
import { isFunction } from '@/utils/is.js'
import { cloneDeep, setObjToString } from '@/utils/common.js'
import store from '@/store'

const codeEnum = {
  SUCCESS: 200,
  NOTFOUND: 404,
  FAIL: 400 || 500,
  TIMEOUT: 10042
}

// 常用的contentType类型
// const contentTypeEnum = {
//   JSON: 'application/json;charset=UTF-8',
//   TEXT: 'text/plain;charset=UTF-8',
//   FORM_URLENCODED: 'application/x-www-form-urlencoded;charset=UTF-8',
//   FORM_DATA: 'multipart/form-data;charset=UTF-8'
// }

// 请求方法
const requestEnum = {
  GET: 'GET',
  POST: 'POST',
  PATCH: 'PATCH',
  PUT: 'PUT',
  DELETE: 'DELETE'
}

const isLoadPage = {
  ISSHIP: true
}

const transform = {
  // 请求前处理config
  requestBeforeHook: (config, options) => {
    // 将token携带在headers中
    const token = store.state.token || uni.getStorageSync('token')
    if (token) {
      config.header = { ...config.header, Authorization:  'Bearer ' + token }
    }
    config.header = { ...config.header, platform: 'MINI',version: '1.0.0' }
    const { apiURL, postJoinParamsToUrl } = options
    config.url = apiURL ? apiURL + config.url : config.url
    // 处理method请求大写--uni-app必须要大写
    config.method = config.method.toUpperCase()
    // post请求--参数需要拼接到url后面
    if (config.method === requestEnum.POST && postJoinParamsToUrl) {
      config.url = setObjToString(config.url, config.data)
    }
    return config
  },
  // 对请求错误进行处理
  responseErrorHook: (errMsg, options) => {
    wx.hideLoading()
    const { errMsgText, isShowError  } = options
    if (isShowError || errMsgText) {
      uni.showToast({
        title: errMsgText || errMsg,
        icon: 'none'
      })
    }
    return null
  },

  // 对返回数据进行处理
  responseSuccessHook: (res, options) => {
    const {
      isTransformResult,
      successMsgText,
      errMsgText,
      isShowSuccess,
      isShowError
    } = options
    const { code, data, desc } = res
    // 是否显示成功提示信息
    // if (isShowSuccess || successMsgText) {
    //   uni.showToast({
    //     title: successMsgText || desc,
    //     icon: 'none'
    //   })
    // }
    // 是否显示错误提示信息
    if ((isShowError || errMsgText)&&code!=200) {
      wx.showToast({
        title: errMsgText || desc,
        icon: 'none'
      })
    }
    let pageUrlArr = ['pages/index/index','pages/my/index']
    console.log(getCurrentPages(),'const routes = getCurrentPages()const routes = getCurrentPages()const routes = getCurrentPages()')
    let codeArr = [1004,1005,1006,1003] // 登录失效
    if (codeArr.includes(code)) {
      store.commit('USERINFO', {})
      store.commit('TOKEN', '')
      uni.setStorageSync('token', '')
      const routes = getCurrentPages()
      if (pageUrlArr.includes(routes[routes.length].route)) return // 底部菜单路由不自动跳转登录
      if(isLoadPage.ISSHIP){
        isLoadPage.ISSHIP = false
        setTimeout(() => {
          isLoadPage.ISSHIP = true
        }, 1000);
        uni.navigateTo({url: '/pagesB/login/index'})
      }
      return
    }
    // code===200
    if (code === 200) {
      wx.hideLoading()
      // 对结果做处理
      if (isTransformResult) {
        return res
      }
      // 不对结果做处理
      return res
    } else {
      wx.hideLoading()
      return res
    }
  }
}

export class VRequest {
  constructor(options) {
    this.options = options
  }

  /**
  * @description 获取options中的转化对象
  * @returns {Object} transform
  */
  getTransform() {
    const { transform } = this.options
    return transform
  }

  /**
  * @description request请求方法
  */
  request(config, options) {
    if (options.isLoading) {
      wx.showLoading({
        icon: 'loading',
        title: '加载中',
        mask: true
      })
    }
    let conf = cloneDeep(config)
    const transform = this.getTransform()
    const { requestBeforeHook, responseErrorHook, responseSuccessHook } = transform || {}
    const { requestOptions } = this.options
    // 合并对象
    const opt = Object.assign({}, requestOptions, options)
    // 处理请求前的config
    if (requestBeforeHook && isFunction(requestBeforeHook)) {
      conf = requestBeforeHook(conf, opt)
    }
    return new Promise(async (resolve, reject) => {
      const [error, res] = await uni.request(conf)
      // 失败--系统或者网络方面的原因
      if (error && error.errMsg === 'request:fail') {
        isFunction(responseErrorHook) && reject(responseErrorHook(error.errMsg, options))
      } else if (res && res.statusCode === codeEnum.SUCCESS) {
        const { data: response } = res
        isFunction(responseSuccessHook) && resolve(responseSuccessHook(response, options))
      } else {
        const _options = {
          isShowError: options.isShowError,
          errMsgText: options.errMsgText || String(res?res.statusCode:'请求超时，请稍后重试')
        }
        isFunction(responseErrorHook) && reject(responseErrorHook('request:fail', _options))
      }
      wx.hideLoading()
    })
  }

}

export const requestInstance = new VRequest({
  // 需要后端添加才能携带过去
  header: {
    platform: 'MINI',
    version: '1.0.0'
  },
  transform,
  // 配置项--以下配置都能在独立的接口请求中被覆盖
  requestOptions: {
    // 是否需要对返回数据进行处理
    isTransformResult: true,
    // post请求的时候参数拼接在url上
    postJoinParamsToUrl: false,
    // 接口地址
    apiURL: BASE_URL
  }
})

// 将request的this指向VRequest
export default requestInstance.request.bind(requestInstance)